package com.ljkj.common.db.basedao;

import java.sql.SQLException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.ljkj.common.db.util.SQLScriptGetter;


public class BaseDAO extends HibernateDaoSupport {
	
	
	private static Configuration config = null;
	private int pageMaxCount = 10;
	private static final Logger log = LoggerFactory.getLogger(BaseDAO.class);
	

	/**
	 * 对多个表进行多个条件查询
	 * @param propertyNames
	 * @param values
	 * @param likePropertyNames
	 * @param likevalues
	 * @param betweenPropertyNames
	 * @param betweenvalues 
	 * @param orderByValues
	 * @param page
	 * @return
	 */
	@SuppressWarnings({"rawtypes", "deprecation"})
	public List findByProperties(Class[] pojos, String[] propertyNames, Object[] values, String[] likePropertyNames, Object[] likevalues, String[] betweenPropertyNames, Object[][] betweenvalues, String[] orderByPropertyNames, Object[] orderByValues, Integer page) {
		log.debug("finding " + pojos + " instance with property: " + propertyNames + ", value: " + values);
		
		final String queryString = SQLScriptGetter.findByProperties(pojos, propertyNames, values, likePropertyNames, likevalues, betweenPropertyNames, betweenvalues, orderByPropertyNames, orderByValues);
		if (page == null) {
			try {
				return this.getHibernateTemplate().executeFind(new HibernateCallback() { 
					public Object doInHibernate(Session session) throws HibernateException, SQLException {
						//System.out.println( session.createQuery(queryString));
						return session.createQuery(queryString).list();
					}
				});
			} catch (RuntimeException re) {
				log.error("find by property name failed", re);
				return null;
			}
			
		} else {
			final int start = (page - 1) * pageMaxCount;
			try {
				return this.getHibernateTemplate().executeFind(new HibernateCallback() {
					public Object doInHibernate(Session session) throws HibernateException, SQLException {
						if (start < 0) {
							return session.createQuery(queryString).list();
						} else {
							return session.createQuery(queryString).setFirstResult(start).setMaxResults(pageMaxCount).list();
						}
					}
				});
			} catch (RuntimeException re) {
				log.error("find by property name failed", re);
				return null;
			}
		}
	}
	
	@SuppressWarnings({ "rawtypes", "deprecation" })
	public List findKnowByProperties(Class[] pojos, String[] propertyNames, Object[] values, String[] likePropertyNames, Object[] likevalues, String[] betweenPropertyNames, Object[][] betweenvalues, String[] orderByPropertyNames, Object[] orderByValues, Integer page) {
		log.debug("finding " + pojos + " instance with property: " + propertyNames + ", value: " + values);
		
		final String queryString = SQLScriptGetter.findByProperties(pojos, propertyNames, values, likePropertyNames, likevalues, betweenPropertyNames, betweenvalues, orderByPropertyNames, orderByValues);
		if (page == null) {
			try {
				return this.getHibernateTemplate().executeFind(new HibernateCallback() { 
					public Object doInHibernate(Session session) throws HibernateException, SQLException {
						System.out.println( session.createQuery(queryString));
						return session.createQuery(queryString).list();  
					}
				});
			} catch (RuntimeException re) {
				log.error("find by property name failed", re);
				return null;
			}
		} else {
			final int start = (page - 1) * this.getPageMaxCount();
			try {
				return this.getHibernateTemplate().executeFind(new HibernateCallback() {
					public Object doInHibernate(Session session) throws HibernateException, SQLException {
						if (start < 0) {
							return session.createQuery(queryString).list();
						} else {
							return session.createQuery(queryString).setFirstResult(start).setMaxResults(pageMaxCount).list();
						}
					}
				});
			} catch (RuntimeException re) {
				log.error("find by property name failed", re);
				return null;
			}
		}
	}
	
	/**
	 * 获得总条数
	 * @param propertyNames
	 * @param values
	 * @param likePropertyNames
	 * @param likevalues
	 * @param betweenPropertyNames
	 * @param betweenvalues
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public Integer getCount(Class[] pojos, String[] propertyNames, Object[] values, String[] likePropertyNames, Object[] likevalues, String[] betweenPropertyNames, Object[][] betweenvalues) {
		log.debug("count " + pojos + " instance with property: " + propertyNames + ", value: " + values);
		final String queryString = SQLScriptGetter.getCountByProperties(pojos, propertyNames, values, likePropertyNames, likevalues, betweenPropertyNames, betweenvalues);
		try {
			return (Integer) getHibernateTemplate().execute(new HibernateCallback() {
				public Integer doInHibernate(Session session) throws HibernateException, SQLException {
					Integer sum = (Integer) session.createQuery(queryString).uniqueResult().hashCode();
					return sum;
				}
			});
		} catch (RuntimeException re) {
			log.error("find by property name failed", re);
			return 0;
		}
	}
	//获得总条数
	@SuppressWarnings("rawtypes")
	public int getCount(Class pojo) {
		log.debug("finding count" + pojo.getName() + " instance with no property");
		Class[] pojos = { pojo };
		final String queryString = SQLScriptGetter.getCountByProperties(pojos, null, null);
		try {
			return (Integer) getHibernateTemplate().execute(new HibernateCallback() {
				public Integer doInHibernate(Session session) throws HibernateException, SQLException {
					Integer sum = session.createQuery(queryString).uniqueResult().hashCode();
					return sum;
				}
			});
		} catch (RuntimeException re) {
			log.error("getCount failed", re);
			return 0;
		}
	}

	/**
	 * @param entities
	 */
	@SuppressWarnings("rawtypes")
	public void delete(Collection entities) {
		log.debug("deleting " + entities + " instances");
		try {
			getHibernateTemplate().deleteAll(entities);
			log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
		}
	}
	
	@SuppressWarnings("rawtypes")
	public List getPojoList(String sql,Integer page) {
		
		 final String tempsql = sql;

		 if (page == null) {
				try {
					return this.getHibernateTemplate().executeFind(new HibernateCallback() { 
						public Object doInHibernate(Session session) throws HibernateException, SQLException {
							System.out.println( session.createQuery(tempsql));
							return session.createQuery(tempsql).list();
						}
					});
				} catch (RuntimeException re) {
					log.error("find IdentifyLog failed", re);
					return null;
				}
			} else {
				final int start = (page - 1) * this.getPageMaxCount();
				final int pageNumber = this.getPageMaxCount();
				try {
					return this.getHibernateTemplate().executeFind(new HibernateCallback() {
						public Object doInHibernate(Session session) throws HibernateException, SQLException {
							if (start < 0) {
								return session.createQuery(tempsql).list();
							} else {
								return session.createQuery(tempsql).setFirstResult(start).setMaxResults(pageNumber).list();
							}
						}
					});
				} catch (RuntimeException re) {
					log.error("find IdentifyLog failed", re);
					return null;
				}
			}

	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public Integer getSize(String sql) {
		 final String tempsql = sql;
		 
		try {
			return (Integer) getHibernateTemplate().execute(new HibernateCallback() {
				public Integer doInHibernate(Session session) throws HibernateException, SQLException {
					Integer sum = (Integer) session.createQuery(tempsql).list().size();
					return sum;
				}
			});	
		} catch (RuntimeException re) {
			log.error("get szie failed", re);
			return 0;
		}
	}
	
	/**
	 * @param entities
	 */
	@SuppressWarnings("rawtypes")
	public void update(Collection entities) {
		log.debug("updating " + entities + " instances");
		try {
			getHibernateTemplate().saveOrUpdateAll(entities);
			log.debug("update successful");
		} catch (RuntimeException re) {
			log.error("update failed", re);
		}
	}
	
	public void update(Object object) {
		log.debug("updating " + object + " instances");
		try {
			getHibernateTemplate().saveOrUpdate(object);
			log.debug("update successful");
		} catch (RuntimeException re) {
			log.error("update failed", re);
			throw re;
		}
	}
	
	/**
	 * @param entities
	 */
	@SuppressWarnings("rawtypes")
	public void save(Collection entities) {
		log.debug("updating " + entities + " instances");
		try {
			if (entities == null){
				return;
			}
			HibernateTemplate hibernateTemplate = getHibernateTemplate();
			Iterator iterator = entities.iterator();
			while (iterator.hasNext()) {
				hibernateTemplate.save(iterator.next());
			}
			log.debug("update successful");
		} catch (RuntimeException re) {
			log.error("update failed", re);
		}
	}
	
	
	/**
	 * @return
	 */
	public int getPageMaxCount() {
		return pageMaxCount;
	}

	/**
	 * @param pageMaxCount
	 */
	public void setPageMaxCount(int pageMaxCount) {
		this.pageMaxCount = pageMaxCount;
	}
	
}
